HAL NAND typical use cases for migration

This section provides information about the HAL NAND Typical use cases for migration.

Note

In HAL1, the read-status API must be called by the user application after the process APIs to determine the memory status before sending another command. In HAL2, the read-status operation is handled internally by the process APIs.

In HAL1, read and write APIs support multi-page operations. whereas in HAL2, these read and write APIs are restricted to a single page operations.

In HAL1, the process APIs pass a structured NAND address including the plane, block and page address, whereas in HAL2, the APIs pass the page/ block index within the entire memory directly as an input parameter.

Program and read one single page in polling mode

Sequence diagram

@startuml

== Initialization and configuration ==

== Process ==
"User Application"->NAND : HAL_NAND_Erase_Block()

"User Application"->NAND : HAL_NAND_Read_Status()
note right: The memory status must be read before sending another command.

"User Application"->NAND : HAL_NAND_Write_Page_8b()

"User Application"->NAND : HAL_NAND_Read_Status()
note right: The memory status must be read before sending another command.


"User Application"->NAND : HAL_NAND_Read_Page_8b()

== De-Initialization ==
"User Application"->NAND : HAL_NAND_DeInit()

@enduml

Code snippet

HAL1

HAL2

uint8_t read_data_buffer[2048];
uint8_t program_data_buffer[2048];
NAND_HandleTypeDef hnand;
uint32_t numPages = 1;
NAND_AddressTypeDef Address;


/* Initialize the nand address  */
Address.Block = 10;
Address.Page  = 50;
Address.Plane  = 0;

HAL_NAND_Erase_Block(&hnand, &Address);
HAL_NAND_Read_Status(&hnand);

HAL_NAND_Write_Page_8b(&hnand, &Address, program_data_buffer, numPages);
HAL_NAND_Read_Status(&hnand);

HAL_NAND_Read_Page_8b(&hnand, &Address, read_data_buffer, numPages);

HAL_NAND_DeInit(&hnand);
uint8_t read_data_buffer[2048];
uint8_t program_data_buffer[2048];
hal_nand_handle_t hnand;
uint32_t page_size = 2048;
uint32_t block_index = 10; /* Block index within the memory = Address.Plane(0) * BlockNbr(2048) + Address.Block(10) */
uint32_t page_index = 690; /* Page index within the memory = Address.Plane(0) * BlockNbr(2048) * BlockSize(64) + Address.Block(10) * BlockSize(64) + Address.Page(50) */






HAL_NAND_EraseBlock(&hnand, block_index);


HAL_NAND_ProgramPage(&hnand, page_index, program_data_buffer, page_size);


HAL_NAND_ReadPage(&hnand, page_index, read_data_buffer, page_size);

HAL_NAND_DeInit(&hnand);

Program and read multiple pages in polling mode

Sequence diagram

@startuml

== Initialization and configuration ==

== Process ==
"User Application"->NAND : HAL_NAND_Erase_Block()

"User Application"->NAND : HAL_NAND_Read_Status()
note right: The memory status must be read before sending another command.

"User Application"->NAND : HAL_NAND_Write_Page_8b()

"User Application"->NAND : HAL_NAND_Read_Status()
note right: The memory status must be read before sending another command.


"User Application"->NAND : HAL_NAND_Read_Page_8b()

== De-Initialization ==
"User Application"->NAND : HAL_NAND_DeInit()

@enduml

Code snippet

HAL1

HAL2

uint8_t read_data_buffer[2048];
uint8_t program_data_buffer[2048];
NAND_HandleTypeDef hnand;
uint32_t numPages = 2;
NAND_AddressTypeDef Address;


/* Initialize the nand address  */
Address.Block = 10;
Address.Page  = 50;
Address.Plane  = 0;

HAL_NAND_Erase_Block(&hnand, &Address);
HAL_NAND_Read_Status(&hnand);

HAL_NAND_Write_Page_8b(&hnand, &Address, program_data_buffer, numPages);
HAL_NAND_Read_Status(&hnand);



HAL_NAND_Read_Page_8b(&hnand, &Address, read_data_buffer, numPages);




HAL_NAND_DeInit(&hnand);
uint8_t read_data_buffer[2048];
uint8_t program_data_buffer[2048];
hal_nand_handle_t hnand;
uint32_t page_size = 2048;
uint32_t block_index = 10;  /* Block index within the memory = Address.Plane(0) * BlockNbr(2048) + Address.Block(10) */
uint32_t page_index = 690;  /* Page index within the memory = Address.Plane(0) * BlockNbr(2048) * BlockSize(64) + Address.Block(10) * BlockSize(64) + Address.Page(50) */






HAL_NAND_EraseBlock(&hnand, block_index);


for (uint8_t page_num = page_index; page_num < (page_index + 2U); page_num++)
{
 HAL_NAND_ProgramPage(&hnand, page_num, program_data_buffer, page_size);
}

for (uint8_t page_num = page_index; page_num < (page_index + 2U); page_num++)
{
 HAL_NAND_ReadPage(&hnand, page_num, read_data_buffer, page_size);
}

HAL_NAND_DeInit(&hnand);

ECC management with the hamming algorithm in polling mode

Note

In HAL1, HAL_NAND_ECC_Enable() enables the ECC computation directly without needing to specify the operation direction (read/program).

In HAL2, with the introduction of new series supporting sequencer command, a new input parameter (access_mode) is added to the ECC enable API.

The access_mode parameter allows you to specify the direction: read, program, or ignore (when specifying the direction is not required).

Sequence diagram

@startuml
== Initialization and configuration ==

== Process ==
"User Application" -> NAND : HAL_NAND_Erase_Block()

"User Application" -> NAND : HAL_NAND_Read_Status()
note right: The memory status is read before sending another command.

"User Application" -> NAND : HAL_NAND_ECC_Enable()

"User Application" -> NAND : HAL_NAND_Write_Page_8b()

"User Application" -> NAND : HAL_NAND_Read_Status()
note right: The memory status is read before sending another command.

"User Application" -> NAND : HAL_NAND_GetECC()

"User Application" -> NAND : HAL_NAND_ECC_Disable()

"User Application" -> NAND : HAL_NAND_ECC_Enable()

"User Application" -> NAND : HAL_NAND_Read_Page_8b()

"User Application" -> NAND : HAL_NAND_GetECC()

"User Application" -> NAND : HAL_NAND_ECC_Disable()

== De-Initialization ==
"User Application" -> NAND : HAL_NAND_DeInit()

@enduml

Code snippet

HAL1

HAL2

uint8_t read_data_buffer[2048];
uint8_t program_data_buffer[2048];
uint32_t ecc_value;
NAND_HandleTypeDef hnand;
uint32_t numPages = 1;
NAND_AddressTypeDef Address;
uint32_t timeout = 1000;

/* Initialize the nand address  */
Address.Block = 10;
Address.Page  = 50;
Address.Plane  = 0;


HAL_NAND_Erase_Block(&hnand, &Address);
HAL_NAND_Read_Status(&hnand);

HAL_NAND_ECC_Enable(&hnand);

HAL_NAND_Write_Page_8b(&hnand, &Address, program_data_buffer, numPages);
HAL_NAND_Read_Status(&hnand);

HAL_NAND_GetECC(&hnand, &ecc_value, timeout);



HAL_NAND_ECC_Disable(&hnand);

HAL_NAND_ECC_Enable(&hnand);

HAL_NAND_Read_Page_8b(&hnand, &Address, read_data_buffer, numPages);

HAL_NAND_GetECC(&hnand, &ecc_value, timeout);

HAL_NAND_ECC_Disable(&hnand);

HAL_NAND_DeInit(&hnand);
uint8_t read_data_buffer[2048];
uint8_t program_data_buffer[2048];
ecc_parity_values_t ecc_values;  /* ECC values are stored within structure */
hal_nand_handle_t hnand;
uint32_t page_size = 2048;
uint32_t block_index = 10; /* Block index within the memory = Address.Plane(0) * BlockNbr(2048) + Address.Block(10) */
uint32_t page_index = 690; /* Page index within the memory = Address.Plane(0) * BlockNbr(2048) * BlockSize(64) + Address.Block(10) * BlockSize(64) + Address.Page(50) */







HAL_NAND_EraseBlock(&hnand, block_index);


HAL_NAND_ECC_Enable(&hnand, HAL_NAND_ACCESS_MODE_IGNORE);

HAL_NAND_ProgramPage(&hnand, page_index, program_data_buffer, page_size);


HAL_NAND_ECC_ReadValue(&hnand, &ecc_values); /* The timeout is removed in HAL2 as waiting for the ECC
                                                flags is hardcoded and handled internally at
                                                 the end of the write and read APIs. */

HAL_NAND_ECC_Disable(&hnand);

HAL_NAND_ECC_Enable(&hnand, HAL_NAND_ACCESS_MODE_IGNORE);

HAL_NAND_ReadPage(&hnand, page_index, read_data_buffer, page_size);

HAL_NAND_ECC_ReadValue(&hnand, &ecc_values);

HAL_NAND_ECC_Disable(&hnand);

HAL_NAND_DeInit(&hnand);